package nju.firework.scene;

import java.util.ArrayList;
import java.util.ListIterator;

import nju.firework.game.cell.Cell;
import nju.firework.game.cell.CellConst;
import nju.firework.game.cell.CellFactory;
import nju.firework.game.main.MainActivity;
import nju.firework.game.main.MainConst;
import nju.firework.hero.Hero;
import nju.firework.hero.HeroTouchHandler;

import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.scene.Scene;
import org.andengine.util.adt.list.SmartList;

import android.util.Log;

public class GameScene extends Scene {

	SmartList<Cell> cellList = new SmartList<Cell>();
	Hero hero;
	Map map;

	MainActivity mMainActivity;
	TimerHandler mapUpdateHandler;
	PhysicsHandler mapMoveHandler;

	public GameScene(MainActivity pMainActivity) {
		// init main loop
		this.mMainActivity = pMainActivity;
		// init map
		map = new Map(pMainActivity);
		// init hero
		hero = new Hero(pMainActivity);
		// add hero
		this.attachChild(hero);
		// register hero handler
		this.setOnSceneTouchListener(new HeroTouchHandler(hero));
		// init cellList
		initCellList();
		// init handler
		mapUpdateHandler = new TimerHandler(0.05f, true, new UpdateCallback());
		// register Handler
		mapMoveHandler = new PhysicsHandler(this);
		this.registerUpdateHandler(mapMoveHandler);
		this.registerUpdateHandler(mapUpdateHandler);
	}

	private void advance() {
		cellList.get(0).detachSelf();
		cellList.removeFirst();
		Cell tmp = CellFactory.createCell(cellList.getLast().getX() + CellConst.WIDTH,MapConst.firstLayerYCoordinate - toHeight(map.getRear()), mMainActivity, map.getRear());
		cellList.add(tmp);
		this.attachChild(tmp);
	}
	
	private void backward(){
		cellList.getLast().detachSelf();
		cellList.removeLast();
		Cell tmp = CellFactory.createCell(cellList.getFirst().getX() - CellConst.WIDTH,MapConst.firstLayerYCoordinate - toHeight(map.getRear()), mMainActivity, map.getRear());
		cellList.add(tmp);
		this.attachChild(tmp);
	}

	private void initCellList() {
		int count = 0;
		for (MapElement m : map.getCurrentMap()) {
			Cell tmp = CellFactory.createCell(count * CellConst.WIDTH,
					MapConst.firstLayerYCoordinate - toHeight(m),
					mMainActivity, m);
			count++;
			this.attachChild(tmp);
			cellList.add(tmp);
		}
	}

	private float toHeight(MapElement m) {
		switch (m) {
		case BLOCK:
			return CellConst.HEIGHT_BLOCK;
		case FLOOR:
			return CellConst.HEIGHT_FLOOR;
		default:
			return 0f;
		}
	}

	class UpdateCallback implements ITimerCallback {
		float currentSpeed = 0f;

		@Override
		public void onTimePassed(TimerHandler pTimerHandler) {
			Log.v("nju.firework.gamescene", "hero X is " + hero.getDistance());
//			if (!checkFirst() && !checkLast()) 
//				ListIterator<Cell> itr = cellList.listIterator();
//				if (currentSpeed != hero.getVelocityX()) {
//					while (itr.hasNext()) {

//						Cell tmp = itr.next();
						// tmp.detachSelf();
						// itr.remove();
						// tmp = CellFactory.createCell(tmp.getX() -
						// hero.getSpeedX(), tmp.getY(), mMainActivity,
						// tmp.getType());
						// tmp.setLinearVelocity(-hero.getSpeedX(), 0);
//						tmp.setLinearVelocity(-hero.getSpeedX(), 0);
						checkFirst();
						checkLast();
//						if(currentSpeed != hero.getVelocityX()){
							currentSpeed = hero.getVelocityX();
							mapMoveHandler.setVelocityX(-currentSpeed*2);
							Log.v("nju.firework.gamescene", "hero X is " + hero.getDistance());
							Log.v("nju.firework.gamescene", "currentSpeedX is " + currentSpeed);
							Log.v("nju.firework.gamescene", "VelocityX is " + mapMoveHandler.getVelocityX());
//						}
//					}
//				}
			
		}

		private boolean checkFirst() {
			if (cellList.get(0).getX() <= hero.getDistance() - 50 -CellConst.WIDTH) {
				map.advance();
				advance();
				return true;
			}
			return false;
		}

		private boolean checkLast() {
			if (cellList.get(cellList.size() - 1).getX() >= hero.getDistance() - 50 + MainConst.CAMERA_WIDTH + CellConst.WIDTH) {
				map.backward();
				backward();
				return true;
			}
			return false;
		}

	}

}
